
import {_toArray} from '../common/utils';
import locationBehavior from "../../../behaviors/location";
const customFormControls = require('../common/custom-form-controls')
const formPath = '../z-form-popup/z-form-popup'
Component({
  behaviors: [customFormControls, locationBehavior],
  relations: {
    [formPath]: {
      type: 'ancestor',
      linked(target) {},
      linkChanged(target) {},
      unlinked(target) {},
    },
  },

  /**
   * 组件的配置
   */
  options: {
    styleIsolation: 'isolated',
    pureDataPattern: /^_/
  },

  /**
   * 组件的传入样式
   */
  externalClasses: ['extra-style'],

  /**
   * 组件的属性列表
   */
  properties: {
    options: {
      type: Array,
      value: []
    },
    value: {
      type: Array,
      value: []
    },
    multiple: {
      type: Boolean,
      value: true,
    },
    tier: {
      type: Number,
      value: 2,
    },
    colors: {
      type: Array,
      value: ['#f0f0f0', '#f8f8f8', '#fff']
    },
    prop: {
      type: String,
      value: '',
    }
  },

  /**
   * 组件的初始数据
   */
  data: {
    _options: {},
    showOptions: [],
    current: [],
  },

  /**
   * 组件的数据监听
   */
  observers: {
    value(val) {
      this.updateValue(val)
      this.updateOptions()
    },
    options(val) {
      this.data._options = this.treeToGroup(this.treeToFlat(val))
      this.updateOptions()
    }
  },

  /**
   * 组件的生命周期
   */
  lifetimes: {
    created() {
      Object.defineProperty(this, 'parent', {
        get: () => this.getRelationNodes(formPath)[0],
      });
    },
    attached() {},
    detached() {},
  },

  /**
   * 组件的方法列表
   */
  methods: {

    treeToFlat(tree, parent, parentPath) {
      let res = []
      tree.forEach((item, index) => {
        let path = `${parentPath || ''}${parentPath ? ',' : ''}${item.value}`
        res.push({
          parent,
          value: item.value,
          label: item.label,
          path: path,
        })
        if (item.children && item.children.length) {
          res.push(...this.treeToFlat(item.children, item.value, path))
        }
      })
      return res
    },

    treeToGroup(list) {
      if (!(list && list.length)) {
        return {}
      }
      let group = {}
      list.forEach(item => {
        if (item.parent) {
          if (group[item.parent]) {
            group[item.parent].push(item)
          } else {
            group[item.parent] = [item]
          }
        } else {
          if (group.first) {
            group.first.push(item)
          } else {
            group.first = [item]
          }
        }
      })
      return group
    },

    updateValue(val) {
      const {
        multiple,
      } = this.data
      if (!(val && val.length)) {
        this.setData({
          current: [],
        })
        return
      }
      if (multiple) {
        this.setData({
          current: val,
        })
      } else {
        this.setData({
          current: [val],
        })
      }
    },

    updateOptions() {
      const {
        _options,
        tier,
      } = this.data
      let showOptions = []
      let currentValue = this.getCurrentValue()
      new Array(tier + 1).fill('').forEach((item, index) => {
        if (index === 0) {
          showOptions[index] = _options.first
        } else {
          if (currentValue[index - 1] && currentValue[index - 1].indexOf('INFINTE') === -1) {
            showOptions[index] = _options[currentValue[index - 1]]
          }
        }
      })
      this.setData({
        showOptions,
      })
    },

    getCurrentValue() {
      const {
        tier,
        current,
        _options,
      } = this.data
      let value = []
      if (current && current.length) {
        value = current[0].slice(0, tier)
      } else {
        new Array(tier + 1).fill('').forEach((item, index) => {
          if (index === 0) {
            if (_options.first && _options.first.length) {
              value[index] = _options.first[0].value
            }
          } else {
            if (_options[value[index - 1]] && _options[value[index - 1]].length) {
              value[index] = _options[value[index - 1]][0].value
            }
          }
        })
      }
      return value
    },

    onClick(e) {
      const {
        tier,
        current,
        multiple,
      } = this.data
      let {
        column,
        active,
        item,
      } = e.currentTarget.dataset
      let newCurrent = []
      this.triggerEvent('customevent', e, { bubbles: true, composed: true })
      if (column === tier) {
        if (item.path.indexOf('INFINTE') !== -1) {
          newCurrent = multiple ? [item.path.split(',')] : item.path.split(',')
        } else {
          if (active) {
            newCurrent = multiple ? (current || []).filter((cur) => cur[tier] !== item.value) : []
            if (!(newCurrent && newCurrent.length)) {
              let cur = item.path.split(',')
              cur[tier] = 'INFINTE'
              newCurrent = [cur]
            }
          } else {
            newCurrent = multiple ? (current || []).concat([item.path.split(',')]).filter((item) => {
              return item[tier] !== 'INFINTE'
            }) : item.path.split(',')
          }
        }
      } else {
        let cur = item.path.split(',')
        let arr = [...new Array(tier + 1)].map((item, index) => {
          if (cur[index]) {
            return cur[index]
          } else {
            return 'INFINTE'
          }
        })
        newCurrent = multiple ? [arr] : arr
      }
      this.updateValue(newCurrent)
      this.updateOptions()
    },

    onConfirm() {
      const {
        prop,
        current,
        multiple,
        showOptions,
        tier
      } = this.data;
      let label = [];
      let newCur = current.map(item => {
        return item[tier]
      });
      if (newCur && newCur.length) {
        if (newCur.indexOf('INFINTE') !== -1) {
          (showOptions[tier - 1] || []).forEach(item => {
            if (current[0] && current[0][1] && current[0][1] === item.value && current[0][1] !== 'INFINTE') {
              label.push(item.label)
            }
          });
        } else {
          (showOptions[tier] || []).forEach(item => {
            if (newCur.indexOf(item.value) !== -1) {
              label.push(item.label)
            }
          });
        }
      }
      (this.parent || {}).data._form[prop] = multiple ? current : current[0];
      (this.parent || {}).data._label[prop] = label.join(' ');
    },

    onReset() {
      this.setData({
        current: [],
      })
      this.updateOptions()
    },
  }
})